package com.wlyy.bcwlw.sys.user.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.wlyy.bcwlw.common.exception.AuthenticationFailedException;
import com.wlyy.bcwlw.common.exception.ServiceException;
import com.wlyy.bcwlw.common.tree.TreeNode;
import com.wlyy.bcwlw.common.utils.CipherUtil;
import com.wlyy.bcwlw.sys.CacheHelper;
import com.wlyy.bcwlw.sys.SecurityFacade;
import com.wlyy.bcwlw.sys.area.service.AreaService;
import com.wlyy.bcwlw.sys.menu.entity.MenuDTO;
import com.wlyy.bcwlw.sys.role.dao.RoleDAO;
import com.wlyy.bcwlw.sys.role.entity.RoleDTO;
import com.wlyy.bcwlw.sys.role.service.RoleService;
import com.wlyy.bcwlw.sys.user.UserConstant;
import com.wlyy.bcwlw.sys.user.dao.UserDAO;
import com.wlyy.bcwlw.sys.user.dao.UserRoleDAO;
import com.wlyy.bcwlw.sys.user.entity.UserDTO;
import com.wlyy.bcwlw.sys.user.entity.UserProfile;
import com.wlyy.bcwlw.sys.user.entity.UserRoleDTO;



@Transactional
@Service
public class UserManageService {
	
	private final static Logger logger = LogManager.getLogger(UserManageService.class);
	@Autowired
	private UserDAO userDAO;
	@Autowired
	private RoleDAO roleDAO;
	@Autowired
	private UserRoleDAO userRoleDAO;
	@Autowired
	private CacheHelper cacheHelper;
	@Autowired
	private RoleService roleService;
	@Autowired
	private AreaService areaService;
	
	/**
	 * 通过用户名判断用户是否存在
	 * 
	 * @param username
	 * @return
	 */
	public boolean isUserExist(String username) {
		Assert.hasText(username);
		UserDTO dto = userDAO.findByUserName(username);
		if (null == dto) {
			return false;
		}
		return true;
	}
	
	/**
	 * 通过用户名和用户ID判断用户是否存在并且不重复
	 * 
	 * @param username
	 * @param userpassword
	 * @return
	 */
	public boolean isUserExist(String username, String userid) {
		Assert.hasText(username);
		UserDTO dto = userDAO.findByUserName(username);
		if (null == dto || dto.getUserId().equals(userid)) {
			return false;
		}
		return true;
	}

	public boolean isUsernumberExist(String usernumber) {
		Assert.hasText(usernumber);
		UserDTO dto = userDAO.findByUserName(usernumber);
		if (null == dto) {
			return false;
		}
		return true;
	}
	
	public UserDTO saveUserInfo(UserDTO userDTO){
		if(StringUtils.isEmpty(userDTO.getUserId())){
			createUser(userDTO);
		}else{
			updateUser(userDTO);
		}
		return userDTO;
	}
	
	public void createUser(UserDTO userDTO){
		Assert.notNull(userDTO);
		if(isExistUserName(userDTO.getUserName())){
			throw new ServiceException("用户名【"+ userDTO.getUserName() +"】已经存在");
		}
		userDTO.setPassword(CipherUtil.encrypt(userDTO.getPassword()));
		userDAO.create(userDTO);
	}
	
	public void updateUser(UserDTO userDTO){
		Assert.notNull(userDTO);
		Assert.hasText(userDTO.getUserId());
		if(StringUtils.isNotEmpty(userDTO.getPassword())){
			userDTO.setPassword(CipherUtil.encrypt(userDTO.getPassword()));
		}
		userDAO.update(userDTO);
	}
	
	public boolean isExistUserName(String userName){
		UserDTO user = new UserDTO();
		user.setUserName(userName);
		int count = userDAO.count(user);
		if(count == 0){
			return false;
		}
		return true;
	}
	
	/**
	 * 
	* @Title. changeMyPassword
	* @Description. 更改个人密码
	* @param oldPassword
	* @param newPassword
	* @return String
	* @exception.
	 */
	public String changeMyPassword(String oldPassword,String newPassword){
		if(StringUtils.isEmpty(oldPassword) || StringUtils.isEmpty(newPassword)){
			return "请将信息补充完整";
		}
		String userId = SecurityFacade.getCurUserId();
		UserDTO myInfo = findById(userId);
		if(!oldPassword.equals(CipherUtil.decrypt(myInfo.getPassword()))){
			return "旧密码不正确";
		}
		myInfo.setPassword(CipherUtil.encrypt(newPassword));
		userDAO.update(myInfo);
		return "更改成功";
	
	}
	
	/**
	 * 
	* @Title. changeMyInfo
	* @Description. 更改个人信息
	* @param userDTO
	* @return String
	 * @throws IOException 
	* @exception.
	 */
	public String changeMyInfo(UserDTO userDTO) {
		if(userDTO!= null && StringUtils.isNotEmpty(userDTO.getUserId())){
			userDAO.update(userDTO);
		}else{
			return "error";
		}
		return  "success";
	}
	
	public boolean removeUserByUserIds(String[] userIds){
		if(userIds == null || userIds.length == 0){
			return false;
		}
		int result =userDAO.removeUserByUserIds(userIds);
		if(result ==0){
			return false;
		}
		return true;
	}
	
	public boolean saveUserOwnRoles(String userId,String[] ownRoles){
		if(StringUtils.isEmpty(userId)){
			return false;
		}
		UserRoleDTO queryUserRoleDTO = new UserRoleDTO();
		queryUserRoleDTO.setUserId(userId);
		List<UserRoleDTO> list = userRoleDAO.queryByObject(queryUserRoleDTO);
		List<String> existList =new ArrayList<String>();
		for(UserRoleDTO userRoleDTO:list){
			if(!ArrayUtils.contains(ownRoles,userRoleDTO.getRoleId())){
				userRoleDAO.remove(userRoleDTO);
			}else{
				existList.add(userRoleDTO.getRoleId());
			}
		}
		
		List<UserRoleDTO> insertList = new ArrayList<UserRoleDTO>();
		
		for(String roleId:ownRoles){
			if(!existList.contains(roleId)){
				UserRoleDTO insertUserRoleDTO = new UserRoleDTO();
				insertUserRoleDTO.setRoleId(roleId);
				insertUserRoleDTO.setUserId(userId);
				insertList.add(insertUserRoleDTO);
			}
		}
		
		if(insertList.size()!=0){
			userRoleDAO.createOfBatch(insertList);
		}
		
		return true;
	}
	
	public UserDTO findById(String userId){
		return userDAO.findById(userId);
	}
	
	public UserDTO findByUsername(String userName){
		return userDAO.findByUserName(userName);
	}
	
	
	public Map<String,Object> showUserOwnRoles(String userId){
		if(StringUtils.isEmpty(userId)){
			return null;
		}
		Map<String,Object> retMap = new HashMap<String,Object> ();
		TreeNode roleTree = roleService.getAllRoleTreeById();
		List<String> ownRoles = userDAO.findUserOwnRolesById(userId);
		retMap.put("roleTree", roleTree);
		retMap.put("ownRoles",ownRoles);
		return retMap;
				
	}
	
	public Map<String,Object> showUserOwnArea(String userId){
		if(StringUtils.isEmpty(userId)){
			return null;
		}
		Map<String,Object> retMap = new HashMap<String,Object> ();
		TreeNode areaTree = areaService.getAreaTreeById(null);
		UserDTO userDTO = userDAO.findById(userId);
		retMap.put("areaTree", areaTree);
		retMap.put("userDTO", userDTO);
		return retMap;
	}
	
	
	/**
	 * 
	* @Title. authenticate
	* @Description. 验证
	* @param up
	* @return
	* @throws AuthenticationFailedException UserProfile
	* @exception.
	 */
	public UserProfile authenticate(UserProfile up) throws AuthenticationFailedException {
		Assert.notNull(up);
		UserDTO userDTO = null;
		if(StringUtils.isNotEmpty(up.getUserId())){
			userDTO = userDAO.findById(up.getUserId());
		}else{
			UserDTO queryUser = new UserDTO();
			queryUser.setUserName(up.getUserName());
			queryUser.setPassword(CipherUtil.encrypt(up.getPassword()));
			List<UserDTO> userDTOList = userDAO.queryUserByUserNameWithPassword(queryUser);
			if (userDTOList.size() >= 2) {
				throw new AuthenticationFailedException("您的姓名与别的用户相同，请用账号登录");
			}else if(userDTOList.size() == 1) {
				userDTO = userDTOList.get(0);
			}
		}
		
		if (userDTO == null) {
			throw new AuthenticationFailedException("认证失败，账号或密码错误");
		}
		
		if(UserConstant.USER_BLOCKED_YES.equals(userDTO.getBlocked())){
			throw new AuthenticationFailedException("认证失败，该帐号已被锁定，请联系管理员解锁");
		}
		
		try {
			BeanUtils.copyProperties(up, userDTO);
		} catch (Exception e) {
			logger.error("拷贝UserDTO到UserProfile出错", e);
		}

		return up;
	}
	
	/**
	 * 
	* @Title. accessDecision
	* @Description. 授权
	* @param up void
	* @exception.
	 */
	public void accessDecision(UserProfile up) {
		if(up == null || UserProfile.ANONYMOUS.equals(up)) {
			return;
		}
		UserDTO userDTO = userDAO.findByUserName(up.getUserName());
		// 加部门信息
		up.setUserAreaId(userDTO.getUserAreaId());
		up.setUserAreaName(userDTO.getUserAreaName());
		List<RoleDTO> roles = cacheHelper.getUserRoles(up.getUserId());
		String[] roleIds = new String[roles.size()];
		int i = 0;
		for (RoleDTO role : roles) {
			roleIds[i++] = role.getId();
		}
		up.setRoles(roles);
		List<MenuDTO> menus = cacheHelper.getUserMenusByRoleId(roleIds);
		String[] menuIds = new String[menus.size()];
		int j = 0;
		for (MenuDTO menu : menus) {
			menuIds[j++] = menu.getId();
		}
		up.setMenus(menus);
		up.setApps(cacheHelper.getUserAppsByMenuIds(menuIds));
		up.setModules(cacheHelper.getUserModuleByMenuIds(menuIds));
		up.setPermissions(cacheHelper.getRolePermissions(roleIds));
	}

	
	
	

	
}
